package com.quaidi.smartlocker.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.quaidi.smartlocker.dto.PackageDepositRequest;
import com.quaidi.smartlocker.dto.PackagePickupRequest;
import com.quaidi.smartlocker.entity.ExpressPackage;
import com.quaidi.smartlocker.entity.LockerCompartment;
import com.quaidi.smartlocker.mapper.ExpressPackageMapper;
import com.quaidi.smartlocker.service.ExpressPackageService;
import com.quaidi.smartlocker.service.LockerCompartmentService;
import com.quaidi.smartlocker.util.PickupCodeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

/**
 * 快递包裹Service实现类
 * 
 * @author QuaiDi
 * @since 2025-08-26
 */
@Service
public class ExpressPackageServiceImpl extends ServiceImpl<ExpressPackageMapper, ExpressPackage> implements ExpressPackageService {

    @Autowired
    private ExpressPackageMapper expressPackageMapper;

    @Autowired
    private LockerCompartmentService lockerCompartmentService;

    @Override
    @Transactional
    public ExpressPackage depositPackage(PackageDepositRequest request) {
        // 检查快递单号是否已存在
        ExpressPackage existingPackage = getByTrackingNumber(request.getTrackingNumber());
        if (existingPackage != null) {
            throw new RuntimeException("快递单号已存在");
        }

        // 分配柜格
        LockerCompartment compartment = lockerCompartmentService.allocateCompartment(request.getPackageSize());
        if (compartment == null) {
            throw new RuntimeException("没有可用的" + request.getPackageSize() + "尺寸柜格");
        }

        // 创建包裹记录
        ExpressPackage expressPackage = new ExpressPackage();
        expressPackage.setTrackingNumber(request.getTrackingNumber());
        expressPackage.setPickupCode(PickupCodeUtil.generatePickupCode());
        expressPackage.setSenderName(request.getSenderName());
        expressPackage.setSenderPhone(request.getSenderPhone());
        expressPackage.setRecipientName(request.getRecipientName());
        expressPackage.setRecipientPhone(request.getRecipientPhone());
        expressPackage.setRecipientAddress(request.getRecipientAddress());
        expressPackage.setExpressCompanyId(request.getExpressCompanyId());
        expressPackage.setCompartmentId(compartment.getId());
        expressPackage.setPackageStatus("DEPOSITED");
        expressPackage.setDepositTime(LocalDateTime.now());
        // 设置过期时间为3天后
        expressPackage.setExpireTime(LocalDateTime.now().plusDays(3));

        expressPackageMapper.insert(expressPackage);
        return expressPackage;
    }

    @Override
    @Transactional
    public ExpressPackage pickupPackage(PackagePickupRequest request) {
        // 根据取件码和电话查找包裹
        ExpressPackage expressPackage = getByPickupCodeAndPhone(request.getPickupCode(), request.getRecipientPhone());
        if (expressPackage == null) {
            throw new RuntimeException("包裹不存在或取件码/电话号码错误");
        }

        // 检查包裹状态
        if (!"DEPOSITED".equals(expressPackage.getPackageStatus())) {
            throw new RuntimeException("包裹已被取走或状态异常");
        }

        // 检查是否过期
        if (expressPackage.getExpireTime() != null && LocalDateTime.now().isAfter(expressPackage.getExpireTime())) {
            throw new RuntimeException("包裹已过期");
        }

        // 更新包裹状态
        expressPackage.setPackageStatus("PICKED_UP");
        expressPackage.setPickupTime(LocalDateTime.now());
        expressPackageMapper.updateById(expressPackage);

        // 释放柜格
        if (expressPackage.getCompartmentId() != null) {
            lockerCompartmentService.releaseCompartment(expressPackage.getCompartmentId());
        }

        return expressPackage;
    }

    @Override
    public ExpressPackage getByTrackingNumber(String trackingNumber) {
        return expressPackageMapper.findByTrackingNumber(trackingNumber);
    }

    @Override
    public ExpressPackage getByPickupCodeAndPhone(String pickupCode, String recipientPhone) {
        return expressPackageMapper.findByPickupCodeAndPhone(pickupCode, recipientPhone);
    }

    @Override
    public ExpressPackage getByPickupCode(String pickupCode) {
        return expressPackageMapper.findByPickupCode(pickupCode);
    }
}